using System.Collections.Generic;
using UnityEngine;

public class TreesManager : MonoBehaviour
{
	public int TreeHP = 200;

	public int DropNum = 10;

	public float DropArea = 3f;

	public Terrain terrain;

	public float BlastArea = 0.5f;

	public GameObject WoodDrop;

	public float ResetTime = 600f;

	private List<int> RemovedIndexList = new List<int>();

	private List<Logger> Loggers = new List<Logger>();

	private TreeInstance[] treesBackup;

	private int ChopIndex;

	private bool hited;

	private float timeTemp;

	private void Start()
	{
		if (terrain == null)
		{
			terrain = (Terrain)UnityEngine.Object.FindObjectOfType(typeof(Terrain));
		}
		BackupTree();
		timeTemp = Time.time;
	}

	public void OnClientStart()
	{
		if ((bool)UnitZ.NetworkGameplay && (bool)UnitZ.NetworkGameplay.environment)
		{
			UnitZ.NetworkGameplay.environment.UpdateTrees(GetRemovedTrees());
		}
	}

	private void Update()
	{
		hited = false;
		if (!(Time.time >= ResetTime + timeTemp))
		{
			return;
		}
		if ((bool)UnitZ.NetworkGameplay && UnitZ.NetworkGameplay.environment.isServer)
		{
			ResetTrees();
			if ((bool)UnitZ.NetworkGameplay.environment)
			{
				UnitZ.NetworkGameplay.environment.UpdateTrees(GetRemovedTrees());
			}
		}
		timeTemp = Time.time;
	}

	public void ResetTrees()
	{
		RemovedIndexList.Clear();
		Loggers.Clear();
		if (terrain != null)
		{
			terrain.terrainData.treeInstances = treesBackup;
		}
	}

	private bool LoggerChecker(int index)
	{
		foreach (Logger logger2 in Loggers)
		{
			if (logger2.index == index)
			{
				return false;
			}
		}
		Logger logger = new Logger();
		logger.index = index;
		logger.HP = TreeHP;
		Loggers.Add(logger);
		return true;
	}

	private bool LoggerApplyDamage(int damage, int index)
	{
		if (!LoggerChecker(index))
		{
			foreach (Logger logger in Loggers)
			{
				if (logger.index == index)
				{
					logger.HP -= damage;
					if (logger.HP <= 0)
					{
						return true;
					}
				}
			}
		}
		return false;
	}

	public void Cuttree(Vector3 position, int damage)
	{
		if (terrain == null)
		{
			return;
		}
		int num = 0;
		TreeInstance[] treeInstances = terrain.terrainData.treeInstances;
		int num2 = 0;
		while (true)
		{
			if (num2 < treeInstances.Length)
			{
				TreeInstance treeInstance = treeInstances[num2];
				Vector3 vector = Vector3.Scale(treeInstance.position, terrain.terrainData.size) + Terrain.activeTerrain.transform.position;
				float num3 = Vector3.Distance(new Vector3(vector.x, position.y, vector.z), position);
				if (num3 < BlastArea && LoggerApplyDamage(damage, num))
				{
					break;
				}
				num++;
				num2++;
				continue;
			}
			return;
		}
		Drop(position);
		RemovedIndexList.Add(num);
		SendARemovedTree(num);
	}

	public void SendARemovedTree(int index)
	{
		if ((bool)UnitZ.NetworkGameplay && UnitZ.NetworkGameplay.environment.isServer)
		{
			RemoveATrees(index);
			if ((bool)UnitZ.NetworkGameplay.environment)
			{
				UnitZ.NetworkGameplay.environment.UpdateTrees(GetRemovedTrees());
			}
		}
	}

	public string GetRemovedTrees()
	{
		string text = string.Empty;
		foreach (int removedIndex in RemovedIndexList)
		{
			text = text + removedIndex + ",";
		}
		return text;
	}

	public void UpdateRemovedTrees(string indexremoved)
	{
		if (terrain == null)
		{
			return;
		}
		RemovedIndexList.Clear();
		string[] array = indexremoved.Split(","[0]);
		for (int i = 0; i < array.Length; i++)
		{
			int result = -1;
			if (int.TryParse(array[i], out result))
			{
				RemovedIndexList.Add(result);
			}
		}
		List<TreeInstance> list = new List<TreeInstance>(terrain.terrainData.treeInstances);
		foreach (int removedIndex in RemovedIndexList)
		{
			list.RemoveAt(removedIndex);
		}
		terrain.terrainData.treeInstances = list.ToArray();
	}

	public void RemoveATrees(int index)
	{
		List<TreeInstance> list = new List<TreeInstance>();
		int num = 0;
		TreeInstance[] treeInstances = terrain.terrainData.treeInstances;
		foreach (TreeInstance item in treeInstances)
		{
			if (num != index)
			{
				list.Add(item);
			}
			num++;
		}
		terrain.terrainData.treeInstances = list.ToArray();
	}

	public void OnHit(DamagePackage dm)
	{
		if (!hited && (bool)UnitZ.NetworkGameplay && UnitZ.NetworkGameplay.environment.isServer)
		{
			Cuttree(dm.Position, dm.Damage);
			hited = true;
		}
	}

	public void Drop(Vector3 position)
	{
		if (!(WoodDrop == null))
		{
			for (int i = 0; i < DropNum; i++)
			{
				UnitZ.gameNetwork.RequestSpawnObject(WoodDrop, DetectGround(position + new Vector3(UnityEngine.Random.Range(0f - DropArea, DropArea), 0f, UnityEngine.Random.Range(0f - DropArea, DropArea))), WoodDrop.transform.rotation);
			}
		}
	}

	private Vector3 DetectGround(Vector3 position)
	{
		if (Physics.Raycast(position, -Vector3.up, out RaycastHit hitInfo, 1000f))
		{
			return hitInfo.point;
		}
		return position;
	}

	private void BackupTree()
	{
		if (!(terrain == null))
		{
			treesBackup = terrain.terrainData.treeInstances;
		}
	}

	private void OnApplicationQuit()
	{
		if (!(terrain == null))
		{
			ResetTrees();
		}
	}
}
